package com.wt.demo;

/**
 * @description
 * @author: wangtao
 * @date:15:48 2019/6/18
 * @email:386427665@qq.com
 */
public class ThreadLocalSourceAndDeadLockDemo {

    static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static void threadLocal() {
        Runnable r = () -> {
            threadLocal.set(1);
            threadLocal.set(2);
            threadLocal.set(3);
        };
        new Thread(r).start();
    }

    public static void main(String[] args) {
        //这个方法主要是打断点去查看threadLocal对象的set方法，
        //调试证明，threadLocal中只是根据当前线程t去获取了每个线程内部的ThreadLocalMap这个对象（t当中的一个属性）
        //但是ThreadLocalMap对象每次set值的时候key都是ThreadLocal对象，而且是同一个对象
        //这里不是很明白，每个线程的ThreadLocalMap都只是存一个值，为什么要用map，换成Object不好么?难道是非要把泛型用上去?
        threadLocal();
        //构造一个死锁
        deadLock();
    }


    private static Object fork1 = new Object();
    private static Object fork2 = new Object();

    private static class PersonRunnable implements Runnable {

        private int num;

        public PersonRunnable(int num) {
            this.num = num;
        }

        @Override
        public void run() {
            if (num == 0) {
                synchronized (fork1) {
                    try {
                        Thread.sleep(500);
                        synchronized (fork2) {
                            System.out.println("person-" + num + " 开始吃饭");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                synchronized (fork2) {
                    try {
                        Thread.sleep(500);
                        synchronized (fork1) {
                            System.out.println("person-" + num + " 开始吃饭");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void deadLock() {
        Thread p1 = new Thread(new PersonRunnable(0));
        p1.setName("person0");
        Thread p2 = new Thread(new PersonRunnable(1));
        p2.setName("person1");
        p1.start();
        p2.start();
    }

}

